package com.teach.service.impl;

import java.util.Date;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.teach.commons.MD5;
import com.teach.dto.LoginUser;
import com.teach.dto.UserRegFormDTO;
import com.teach.dto.UserSearch;
import com.teach.entity.UserInfo;
import com.teach.exception.CodeException;
import com.teach.mapper.RoleInfoMapper;
import com.teach.mapper.UserInfoMapper;
import com.teach.service.UserService;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

	@Autowired
	private UserInfoMapper mapper;

	@Autowired
	private RoleInfoMapper mapper1;

	@Value("${reg-role-id:0}")
	private Integer regRoleId = 0;

	@Value("${reg-user-locked:false}")
	private Boolean regUserLocked = false;

	@Transactional
	@Override
	public void reg(UserRegFormDTO form) {
		if (StringUtils.isEmpty(form.getUserName())) {
			throw new CodeException(10);
		}
		if (!form.getUserName().matches("^[a-zA-Z]\\w{2,19}$")) {
			throw new CodeException(11);
		}
		if (StringUtils.isEmpty(form.getUserPwd())) {
			throw new CodeException(12);
		}
		if (!form.getUserPwd().matches("^.{3,20}$")) {
			throw new CodeException(13);
		}
		if (existsUserName(form.getUserName())) {
			throw new CodeException(9);
		}
		if(StringUtils.isEmpty(form.getUserTel())) {
			throw new CodeException(14);
		}
		if(!form.getUserTel().matches("^1\\d{10}$")) {
			throw new CodeException(15);
		}
		if (existsUserTel(form.getUserTel())) {
			throw new CodeException(7);       
		}
		UserInfo user = new UserInfo();
		BeanUtils.copyProperties(form, user);
		user.setUserRegisterTime(new Date());
		user.setRoleId(regRoleId);
		user.setUserLocked(regUserLocked);
		user.setUserPwd(MD5.encode(user.getUserPwd()));

		log.debug("form:{}", form);
		log.debug("user:{}", user);
		try {
			mapper.insertSelective(user);
		} catch (Exception ex) {
			throw new CodeException(0, ex);
		}
	}

	@Override
	public LoginUser login(String userName, String pwd) {
		UserInfo userInfo = null;
		if (userName.matches("^\\d+$")) {
			userInfo = mapper.selectByUserTel(userName);
			throw new CodeException(7);
		} else {
			userInfo = mapper.selectByPrimaryKey(userName);
			if (userInfo == null) {
				throw new CodeException(1);
			}
		}
		if (!userInfo.getUserPwd().equals(MD5.encode(pwd))) {
			throw new CodeException(2);
		}
		if (userInfo.getUserLocked()) {
			throw new CodeException(3);
		}

		LoginUser user = new LoginUser();
		BeanUtils.copyProperties(userInfo, user);
		user.setRoleName(mapper1.selectByPrimaryKey(userInfo.getRoleId()).getRoleName());
		return user;
	}

	@Cacheable(value = "user", key = "#userName")
	@Override
	public UserInfo get(String userName) {
		return mapper.selectByPrimaryKey(userName);
	}

	@Override
	public void modify(String userName, String userPwd) {
		UserInfo user = new UserInfo();
		user.setUserName(userName);
		user.setUserPwd(MD5.encode(userPwd));
		mapper.updateByPrimaryKeySelective(user);
	}

	@Override
	public void modify(String userName, String newUserPwd, String oldUserPwd) {
		UserInfo user = mapper.selectByPrimaryKey(userName);
		if (!user.getUserPwd().equals(MD5.encode(oldUserPwd))) {
			throw new CodeException(8);
		}
		modify(userName, newUserPwd);
	}

	@CacheEvict(value = "user", key = "#user.userName")
	@Override
	public void modify(UserInfo user) {
		log.debug(user.toString());
		mapper.updateByPrimaryKeySelective(user);
	}

	@Override
	public Boolean existsUserName(String userName) {
		return mapper.selectByPrimaryKey(userName) != null;
	}

	@Override
	public Boolean existsUserTel(String userTel) {
		return mapper.selectByUserTel(userTel) != null;
	}

	@Override
	public List<UserInfo> list(UserSearch search) {
		PageInfo<UserInfo> page = PageHelper.startPage(search.getCurrent(), search.getRowMax(), false).doSelectPageInfo(()->{
			mapper.select(search);
		});
		return page.getList();
	}

	@Override
	public PageInfo<UserInfo> page(UserSearch search) {
		PageInfo<UserInfo> page = PageHelper.startPage(search.getCurrent(), search.getRowMax()).doSelectPageInfo(()->{
			mapper.select(search);
		});
		return page;
	}

	@Override
	public List<UserInfo> selectAll() {
		List<UserInfo> infos = mapper.selectAll();
		return infos;
	}

}
